package com.hyz.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.listener.ReadListener;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hyz.model.asset.Asset;
import com.hyz.model.asset.UploadAsset;
import com.hyz.service.AssetService;
import com.hyz.service.impl.AssetServiceImpl;
import com.hyz.utils.Conversion;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author HGD
 * @date 2022/9/23 17:50
 */
@Component
public class UploadAssetListener implements ReadListener<UploadAsset> {
    List<Asset> successList = new ArrayList<>();
    List<Asset> failedList = new ArrayList<>();
    private final AssetService assetService;
    private final Conversion conversion;

    public UploadAssetListener() {
        assetService = new AssetServiceImpl();
        conversion = new Conversion();
    }

    /**
     * 读取每行数据的时候回执行此方法
     *
     * @param uploadAsset     one row value. It is same as {@link AnalysisContext#readRowHolder()}
     * @param analysisContext analysis context
     */
    @Override
    public void invoke(UploadAsset uploadAsset, AnalysisContext analysisContext) {
        Asset asset = conversion.getAsset(uploadAsset);
        QueryWrapper<Asset> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Asset::getAssetId, asset.getAssetId());
        if (Objects.isNull(assetService.getOne(wrapper))) {
            successList.add(asset);
        } else {
            failedList.add(asset);
        }
    }

    /**
     * 在整个excel sheet解析完毕后执行的逻辑。
     *
     * @param analysisContext 内容
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        assetService.saveBatch(successList);
    }

    /**
     * 当任何一个侦听器执行错误报告时，所有侦听器都将接收此方法。 如果在此处引发异常，则整个读取将终止。
     * 这里是处理读取excel异常的
     *
     * @param exception 错误
     * @param context   上下文
     * @throws Exception 异常
     */
    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        ReadListener.super.onException(exception, context);
    }

    /**
     * 读取每行excel表头时会执行此方法
     *
     * @param headMap 上下文
     * @param context 上下文
     */
    @Override
    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
        ReadListener.super.invokeHead(headMap, context);
    }

    /**
     * 如果有额外的单元格信息返回就用此方法处理
     *
     * @param extra   extra information
     * @param context analysis context
     */
    @Override
    public void extra(CellExtra extra, AnalysisContext context) {
        ReadListener.super.extra(extra, context);
    }

    /**
     * 用来控制是否读取下一行的策略
     *
     * @param context 上下文
     * @return 是否存在
     */
    @Override
    public boolean hasNext(AnalysisContext context) {
        return ReadListener.super.hasNext(context);
    }
}
